package com.wa.util;

import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * HTTP相关的操作
 *
 * @author Dawei
 */

public class HttpUtil {

    //private static Logger logger = Logger.getLogger(HttpUtil.class);

    /**
     * 设置cookie
     *
     * @param response    应答
     * @param cookieName  cookie名
     * @param cookieValue cookie值
     * @param time        cookie生存时间
     */
    public static void addCookie(HttpServletResponse response, String cookieName, String cookieValue, int time) {
        // //System.out.println("write :" + cookieName + " " + cookieValue);
        try {
            if (cookieValue != null)
                cookieValue = URLEncoder.encode(cookieValue, "UTF-8");

        } catch (Exception ex) {
            ex.printStackTrace();
            // //System.out.println(ex);
        }

        Cookie cookie = new Cookie(cookieName, cookieValue);
        cookie.setMaxAge(time);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public static void addCookie(HttpServletResponse response, String domain, String path, String cookieName, String cookieValue, int time) {
        try {
            cookieValue = URLEncoder.encode(cookieValue, "UTF-8");
        } catch (Exception ex) {
        }
        Cookie cookie = new Cookie(cookieName, cookieValue);
        cookie.setMaxAge(time);
        cookie.setDomain(domain);
        cookie.setPath(path);
        response.addCookie(cookie);
        // //System.out.println("write " + cookieName);
    }

    public static void addCookie1(HttpServletResponse response, String cookieName, String cookieValue, int time) {
        Cookie cookie = new Cookie(cookieName, cookieValue);
        cookie.setMaxAge(time);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public static String getCookieValue(HttpServletRequest request, String cookieName, String domain, String path) {
        Cookie[] cookies = request.getCookies();

        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {
                if (domain.equals(cookies[i].getDomain()) && path.equals(cookies[i].getPath())
                        && cookieName.equals(cookies[i].getName())) {
                    return cookies[i].getValue();
                }
            }
        }
        return null;
    }

    /**
     * 根据cookie名称取得cookie的值
     *
     * @param request    request对象
     * @param cookieName cookie名称
     * @return string cookie的值 当取不到cookie的值时返回null
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {

                if (cookieName.equals(cookies[i].getName())) {
                    return cookies[i].getValue();
                }
            }
        }
        return null;
    }

    public static String getIpAddress(HttpServletRequest request) {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    public static String getUserAgent(HttpServletRequest request) {
        if (request == null) {
            return "";
        }
        String userAgent = request.getHeader("User-Agent");
        if (CommUtils.isEmpty(userAgent)) {
            return "";
        }
        return userAgent;
    }



    

    /**
     * 通过ua判断终端来源。
     *
     * @param ua
     * @return
     */
    @Deprecated
    public static String getTerminalByUserAgent(String ua) {
        // UA改变需要修正此方法
        if (ua == null) {
            return "unknown";
        }
        String sr = ua.toLowerCase();
        if (sr.startsWith("android")) {
            return "android-app";
        } else if (sr.startsWith("ios")) {
            return "ios-app";
        } else {
            StringBuilder userAgent = new StringBuilder("[");
            userAgent.append(ua);
            userAgent.append("]");
            int indexOfMac = userAgent.indexOf("Mac OS X");
            int indexOfWindows = userAgent.indexOf("Windows NT");
            int indexOfIE = userAgent.indexOf("MSIE");
            int indexOfIE11 = userAgent.indexOf("rv:");
            int indexOfFF = userAgent.indexOf("Firefox");
            int indexOfSogou = userAgent.indexOf("MetaSr");
            int indexOfChrome = userAgent.indexOf("Chrome");
            int indexOfMQQBrowser = userAgent.indexOf("MQQBrowser");
            int indexOfSafari = userAgent.indexOf("Safari");
            boolean isMac = indexOfMac > 0;
            boolean isWindows = indexOfWindows > 0;
            boolean isLinux = userAgent.indexOf("Linux") > 0;
            boolean containIE = indexOfIE > 0 || (isWindows && (indexOfIE11 > 0));
            boolean containFF = indexOfFF > 0;
            boolean containSogou = indexOfSogou > 0;
            boolean containChrome = indexOfChrome > 0;
            boolean containMQQBrowser = indexOfMQQBrowser > 0;
            boolean containSafari = indexOfSafari > 0;
            String browser = "";
            if (containSogou) {
                if (containIE) {
                    browser = "搜狗" + userAgent.substring(indexOfIE, indexOfIE + "MSIE x.x".length());
                } else if (containChrome) {
                    browser = "搜狗" + userAgent.substring(indexOfChrome, indexOfChrome + "Chrome/xx".length());
                }
            } else if (containChrome) {
                browser = userAgent.substring(indexOfChrome, indexOfChrome + "Chrome/xx".length());
            } else if (containMQQBrowser) {
                int indexOfMQQBrowserVersion = userAgent.indexOf("Version");
                browser = "MQQBrowser "
                        + userAgent.substring(indexOfMQQBrowserVersion, indexOfMQQBrowserVersion + "Version/x.x.x".length());
            } else if (containSafari) {
                int indexOfSafariVersion = userAgent.indexOf("Version");
                browser = "Safari "
                        + userAgent.substring(indexOfSafariVersion, indexOfSafariVersion + "Version/x.x.x".length());
            } else if (containFF) {
                browser = userAgent.substring(indexOfFF, indexOfFF + "Firefox/xx".length());
            } else if (containIE) {
                if (indexOfIE11 > 0) {
                    browser = "MSIE 11";
                } else {
                    browser = userAgent.substring(indexOfIE, indexOfIE + "MSIE x.x".length());
                }
            }
            String os = "";
            if (isMac) {
                os = userAgent.substring(indexOfMac, indexOfMac + "MacOS X xxxx".length());
            } else if (isLinux) {
                os = "Linux";
            } else if (isWindows) {
                os = "Windows ";
                String version = userAgent.substring(indexOfWindows + "Windows NT".length(), indexOfWindows
                        + "Windows NTx.x".length());
                if ("5.0".equals(version.trim())) {
                    os += "2000";
                } else if ("5.1".equals(version.trim())) {
                    os += "XP";
                } else if ("5.2".equals(version.trim())) {
                    os += "2003";
                } else if ("6.0".equals(version.trim())) {
                    os += "Vista";
                } else if ("6.1".equals(version.trim())) {
                    os += "7";
                } else if ("6.2".equals(version.trim())) {
                    os += "8";
                } else if ("6.3".equals(version.trim())) {
                    os += "8.1";
                }
            }
            return browser + " |" + os;
        }

    }

    /**
     * 获取服务器的本地地址
     *
     * @return IP
     * @author 水墨
     * @version 2015-10-28
     */
    public static String getLocalIpAddress() {
        List<NetworkInterface> netlist = new ArrayList<NetworkInterface>();
        try {
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();// 获取当前环境下的所有网卡
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
                if (ni.isLoopback()) {
                    continue;// 过滤环回网卡
                }
                netlist.add(0, ni);// 倒置网卡顺序
            }
            /**
             * 用上述方法获取所有网卡时，得到的顺序与服务器中用ipconfig命令看到的网卡顺序相反，
             * 因此，想要从第一块网卡开始遍历时，需要将Enumeration<NetworkInterface>中的元素倒序
             * */
            for (NetworkInterface list : netlist) { // 遍历每个网卡
                Enumeration<InetAddress> cardipaddress = list.getInetAddresses();// 获取网卡下所有IP
                while (cardipaddress.hasMoreElements()) {// 将网卡下所有IP地址取出
                    InetAddress ip = cardipaddress.nextElement();
                    if (!ip.isLoopbackAddress()) {
                        if (ip.getHostAddress().equalsIgnoreCase("127.0.0.1")) {
                            // 过滤localhost
                            continue;
                        }
                        if (ip instanceof Inet6Address) {
                            // 过滤ipv6地址
                            continue;
                        }
                        if (ip instanceof Inet4Address) {
                            // 返回ipv4地址
                            return ip.getHostAddress();
                        }
                    }
                    return InetAddress.getLocalHost().getHostAddress();// 默认返回
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return StringUtils.EMPTY;
    }

 
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlName = url + "?" + param;
            URL realUrl = new URL(urlName);
            // 打开和URL之间的连接  
            URLConnection conn = realUrl.openConnection();
            conn.setConnectTimeout(60000);
            conn.setReadTimeout(30000);

            // 设置通用的请求属性  
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 linux");
            conn.setRequestProperty("Content-Type", "application/json");
            // 建立实际的连接  
            conn.connect();
            // 获取所有响应头字段  
            //Map<String, List<String>> map = conn.getHeaderFields();
            // 遍历所有的响应头字段  
            /*for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }*/
            // 定义BufferedReader输入流来读取URL的响应  
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
            return "请求异常";
        }
        // 使用finally块来关闭输入流  
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String sendPost(String url, String param){
        //logger.error("url=" + url);
        //logger.error("param=" + param);
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            //logger.error("发起链接=" + conn);
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 linux");
            conn.setRequestProperty("Content-Type", "application/json");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(60000);
            conn.setReadTimeout(300000);
            conn.setRequestProperty("Charset", "UTF-8");
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            //logger.error("out刷新=" + conn);
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
            return "请求异常";
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}
